﻿using Scrat.Core;
using Scrat.Core.Screenshot;
using Scrat.Core.Screenshot.WinFeatures;
using Scrat.Core.Server;
using Sunny.UI;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Windows;
using System.Windows.Forms;

namespace Scrat.Teacher.Pages
{
    public partial class ScreenBroadcastPage : UIPage
    {
        private MainForm _parent;
        private StreamingServer _streamingServer;

        private string _serverIPAddr = "127.0.0.1";
        private int _screenSharingPort = 2333;
        
        public ScreenBroadcastPage(MainForm parent)
        {
            InitializeComponent();
            _parent = parent;
        }

        private void ScreenBroadcastPage_Load(object sender, EventArgs e)
        {
            InitData();
        }

        private void ScreenBroadcastPage_Shown(object sender, EventArgs e)
        {
            _parent.ServerConfigChangedEvent += OnServerConfigChanged;
        }
        private void OnServerConfigChanged(string serverIPAddr, int screenShanringPort)
        {
            /*
             * 1. 服务为null, 赋值
             * 2. 服务不为null, 但是没有启动 , 赋值
             * 3. 服务不为null, 并且正在运行, 那么return 
             */
            if (_streamingServer != null && _streamingServer.IsRunning) { return; }

            _serverIPAddr = serverIPAddr;
            _screenSharingPort = screenShanringPort;
        }

        private void ScreenBroadcastPage_FormClosed(object sender, System.Windows.Forms.FormClosedEventArgs e)
        {
            _streamingServer?.Stop();
        }

        private void btnStartStopBoradcast_Click(object sender, EventArgs e)
        {
            if (btnStartStopBoradcast.Text.ToString() == UiConstants.StartBoardcast)
            {
                try
                {
                    // 开始广播
                    ConfigureUiAtServerStartup();
                    
                    var fps = GetFpsFromComboBox(cbFPS.Text);
                    StartStreamingServer(IPAddress.Parse(_serverIPAddr), _screenSharingPort,
                        fps);

                    ShowSuccessNotifier("屏幕共享服务启动成功:" + _serverIPAddr + ":" + _screenSharingPort);
                }
                catch (FormatException)
                {
                    UIMessageDialog.ShowErrorDialog(this, UiConstants.PortOrIpErrorMessage);
                    ConfigureUiWhenServerStoped();
                }
                catch (SocketException)
                {
                    UIMessageDialog.ShowErrorDialog(this, UiConstants.IpAddressErrorMessage);
                    ConfigureUiWhenServerStoped();
                }

            }
            else
            {
                _streamingServer.Stop();
                ConfigureUiWhenServerStoped();
            }
            
        }

        /// <summary>
        /// 数据初始化
        /// </summary>
        private void InitData()
        {
            cbFPS.SelectedIndex = 1;// default 60fps
            cbScreenResolution.SelectedIndex = 0;// default 1920x1080
            // 当前运行的软件下拉框
            var runningApps = GetInfoAboutRunningApps();
            foreach (var runningApp in runningApps)
            {
                cbAppWindow.Items.Add(runningApp);
            }
            cbAppWindow.SelectedIndex = 0;
        }

        /// <summary>
        /// 屏幕广播模式单选按钮切换事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rbAppWindowModel_CheckedChanged(object sender, EventArgs e)
        {
            if (rbFullScreenModel.Checked)
            {
                gbFullScreen.Enabled = true;
                gbAppWindow.Enabled = false;
            }
            else
            {
                gbFullScreen.Enabled = false;
                gbAppWindow.Enabled = true;
            }
        }

        /// <summary>
        /// Starts the streaming server.
        /// </summary>
        /// <param name="ipAddress">IP address of the server.</param>
        /// <param name="port">Server port.</param>
        /// <param name="fps">FPS stream.</param>
        private void StartStreamingServer(IPAddress ipAddress, int port, Fps fps)
        {
            if (rbFullScreenModel.Checked)
            {
                var resolution = GetResolutionFromComboBox(cbScreenResolution.Text);
                bool isDisplayCursor = chShowCursorFullScreen.Checked;

                _streamingServer = StreamingServer.GetInstance(resolution, fps, isDisplayCursor);
                _streamingServer.Start(ipAddress, port);
            }
            else if (rbAppWindowModel.Checked)
            {
                string applicationName = cbAppWindow.Text;
                bool isDisplayCursor = chShowCursorAppWindow.Checked;

                _streamingServer = StreamingServer.GetInstance(applicationName, fps, isDisplayCursor);
                _streamingServer.Start(ipAddress, port);
            }
        }

        /// <summary>
        /// Provides FPS Stream.
        /// </summary>
        /// <param name="selectedFps">FPS selected by user.</param>
        /// <returns>FPS.</returns>
        private static Fps GetFpsFromComboBox(string selectedFps)
        {
            switch (selectedFps)
            {
                case UiConstants.OneHundredAndTwentyFps:
                    return Fps.OneHundredAndTwenty;
                case UiConstants.SixtyFps:
                    return Fps.Sixty;
                case UiConstants.ThirtyFps:
                    return Fps.Thirty;
                case UiConstants.FifteenFps:
                    return Fps.Fifteen;
                default:
                    return Fps.Thirty;
            }
        }

        /// <summary>
        /// Provides stream resolutions.
        /// </summary>
        /// <param name="selectedScreenResolution">Resolution selected by user.</param>
        /// <returns>Resolution.</returns>
        private static Resolution.Resolutions GetResolutionFromComboBox(string selectedScreenResolution)
        {
            switch (selectedScreenResolution)
            {
                case UiConstants.OneThousandAndEightyP:
                    return Resolution.Resolutions.OneThousandAndEightyP;
                case UiConstants.SevenHundredAndTwentyP:
                    return Resolution.Resolutions.SevenHundredAndTwentyP;
                case UiConstants.FourHundredAndEightyP:
                    return Resolution.Resolutions.FourHundredAndEightyP;
                case UiConstants.ThreeHundredAndSixtyP:
                    return Resolution.Resolutions.ThreeHundredAndSixtyP;
                case UiConstants.TwoHundredAndFortyP:
                    return Resolution.Resolutions.TwoHundredAndFortyP;
                default:
                    return Resolution.Resolutions.SevenHundredAndTwentyP;
            }
        }

        private static IEnumerable<string> GetInfoAboutRunningApps()
        { 
            return RunningApplications.GetListOfRunningApps();
        }


        public delegate void ServerStatusChangedDelegate(bool serverStatus);
        public event ServerStatusChangedDelegate ServerStatusChangedEvent;

        /// <summary>
        /// 配置屏幕广播启动状态的Ui状态
        /// </summary>
        private void ConfigureUiAtServerStartup()
        {
            ServerStatusChangedEvent?.Invoke(true);

            gbFullScreen.Enabled = false;
            gbAppWindow.Enabled = false;
            gbBoradcastModel.Enabled = false;

            btnStartStopBoradcast.Text = UiConstants.StopBoardcast;
            btnStartStopBoradcast.Symbol = 61517;// 方形按钮
            btnStartStopBoradcast.FillColor = Color.FromKnownColor(KnownColor.IndianRed);
            btnStartStopBoradcast.FillHoverColor = Color.FromArgb(219, 111, 111);
            btnStartStopBoradcast.FillPressColor = Color.FromArgb(180, 82, 82);
        }

        /// <summary>
        /// 配置当屏幕广播停止时的UI状态
        /// </summary>
        private void ConfigureUiWhenServerStoped()
        {
            ServerStatusChangedEvent?.Invoke(false);

            if (rbFullScreenModel.Checked)
            {
                gbFullScreen.Enabled = true;
                gbAppWindow.Enabled = false;
            }
            else
            {
                gbFullScreen.Enabled = false;
                gbAppWindow.Enabled = true;
            }
            gbBoradcastModel.Enabled = true;

            btnStartStopBoradcast.Text = UiConstants.StartBoardcast;
            btnStartStopBoradcast.Symbol = 61515;// 三角形按钮
            btnStartStopBoradcast.FillColor = Color.FromArgb(80, 160, 255);
            btnStartStopBoradcast.FillHoverColor = Color.FromArgb(115, 179, 255);
            btnStartStopBoradcast.FillPressColor = Color.FromArgb(64, 128, 204);
        }

       
    }
}
